﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Threading;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Diagnostics;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.StorageClient;
using System.Reflection;
using System.IO;

namespace VideoProcessor
{
    public class WorkerRole : RoleEntryPoint
    {
        #region fields
        private bool _working = false;
        private System.Timers.Timer _reqCheckTimer;
        private VideoConverter _vConv;
        #endregion

        #region Overrides
        #region Run
        public override void Run()
        {
            // This is a sample worker implementation. Replace with your logic.
            Trace.WriteLine("VideoProcessor entry point called", "Information");

            this.Initialize();
                        
            while (true)
            {
                Thread.Sleep(10000);
                Trace.WriteLine("Working", "Information");
            }
        }
        #endregion

        #region OnStart
        public override bool OnStart()
        {
            DiagnosticMonitorConfiguration diagConfig = DiagnosticMonitor.GetDefaultInitialConfiguration();
            diagConfig.Logs.ScheduledTransferPeriod = TimeSpan.FromMinutes(2);
            diagConfig.Logs.ScheduledTransferLogLevelFilter = LogLevel.Verbose;

            DiagnosticMonitor.Start("DiagnosticsConnectionString", diagConfig);

            // For information on handling configuration changes
            // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
            RoleEnvironment.Changing += RoleEnvironmentChanging;

            // This code sets up a handler to update CloudStorageAccount instances when their corresponding
            // configuration settings change in the service configuration file.
            CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>
            {
                // Provide the configSetter with the initial value
                configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));

                RoleEnvironment.Changed += (s, arg) =>
                {
                    if (arg.Changes.OfType<RoleEnvironmentConfigurationSettingChange>()
                        .Any((change) => (change.ConfigurationSettingName == configName)))
                    {
                        // The corresponding configuration setting has changed, propagate the value
                        if (!configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)))
                        {
                            // In this case, the change to the storage account credentials in the
                            // service configuration is significant enough that the role needs to be
                            // recycled in order to use the latest settings. (for example, the 
                            // endpoint has changed)
                            RoleEnvironment.RequestRecycle();
                        }
                    }
                };
            });

            return base.OnStart();
        }
        #endregion
        #endregion

        #region Methods

        #region Initialize
        private void Initialize()
        {
            this._vConv = new VideoConverter();

            this._reqCheckTimer = new System.Timers.Timer(20000); // 20 seconds
            this._reqCheckTimer.Elapsed += new System.Timers.ElapsedEventHandler(_reqCheckTimer_Elapsed);
            this._reqCheckTimer.Start();
        }
        #endregion

        #endregion

        #region EventHandlers

        #region RoleEnvironemntChanging
        private void RoleEnvironmentChanging(object sender, RoleEnvironmentChangingEventArgs e)
        {
            // If a configuration setting is changing
            if (e.Changes.Any(change => change is RoleEnvironmentConfigurationSettingChange))
            {
                // Set e.Cancel to true to restart this role instance
                e.Cancel = true;
            }
        }
        #endregion

        #region TimerElapsed
        void _reqCheckTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (this._working) return;
            this._working = true;
            this._vConv.CheckWork();
            this._working = false;
        }
        #endregion
        #endregion
    }
}
